#ifdef _MSC_VER
#include "timetools.h"

#define _WINSOCKAPI_
#include <Windows.h>
#include <winsock2.h>
#include <stdint.h>

// see: https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows
// Needed since Windows does not have any equivalent to gettimeofday
static constexpr uint64_t EPOCH = ((uint64_t)116444736000000000ULL);

int timetools::gettimeofday(struct timeval* tp, struct timezone* tzp)
{
  // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
  // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
  // until 00:00:00 January 1, 1970 

  SYSTEMTIME  system_time;
  FILETIME    file_time;
  uint64_t    time;

  GetSystemTime(&system_time);
  SystemTimeToFileTime(&system_time, &file_time);
  time = ((uint64_t)file_time.dwLowDateTime);
  time += ((uint64_t)file_time.dwHighDateTime) << 32;

  tp->tv_sec = (long)((time - EPOCH) / 10000000L);
  tp->tv_usec = (long)(system_time.wMilliseconds * 1000);

  // According to:
  // https://www.man7.org/linux/man-pages/man2/gettimeofday.2.html
  // The use of the timezone struct is obsolete.
  // When gettimeofday() is called in Linux, the timezone struct's
  // members are all set to 0.
  // Without the following lines of code, it appears that these 
  // members are not initialized, i.e., they are filled with garbage
  // data. In one instance of testing, we observed a value of
  // ~-800,000,000 in both attributes of timezone.
  // It appears that this is the cause of TPJ-2885.
  // https://jira.aeye.ai/browse/TPJ-2885
  // As such, the setTime command fails in Windows, and the time
  // on the sensor ddoes not get updated on connection.
  // Explicitly initializing the members of timezone to 0 in 
  // Windows to address this issue.
  tzp->tz_dsttime = 0;
  tzp->tz_minuteswest = 0;

  return 0;
}
#endif // Windows Time Structs